#include "Map.h"

#include <fstream>

#include "renderer/GameRenderer.h"
#include "json/json.h"

namespace VectorTD
{
	const GLfloat MAP_SIZE = 10.0f;

	Map::Map(const char* p_mapPath)
		: m_cells()
		, m_modelMat(glm::mat4(1.0f))
		, m_path()
	{
		LOG("->MAP::MAP(%s)\n", p_mapPath);

		std::string line("");
		std::string file("");
		std::ifstream myfile(p_mapPath);
		if(myfile.is_open())
		{
			while (myfile.good())
			{
				getline(myfile,line);
				file += line;
				file += "\n";
			}
			myfile.close();
		}
		else
			LOG("Error while opening file: %s\n", p_mapPath);

		Json::Value root;
		Json::Reader reader;
		bool parsedSuccess = reader.parse(file, root, false);
		std::pair<int, int> startPoint = std::make_pair(-1, -1);
		if(parsedSuccess)
		{
			LOG("Map json successfully parsed: %s\n", p_mapPath);

			// ========================================================================
			// We create the list of Cell

			const Json::Value map_lines = root["map_area"];
			LOG("Map size: %d\n", map_lines.size());

			m_cells.resize(map_lines.size());
			for(unsigned int i = 0 ; i < map_lines.size() ; i++)
			{
				m_cells[i].resize(map_lines.size());
			}
			 
			for(unsigned int i = 0 ; i < map_lines.size() ; i++)
			{
				std::string line = map_lines[i].asString();
				if(line.size() != map_lines.size())
				{
					LOG("ERROR: Line[%d] size = %d does not fit map height = %d", i, line.size(), map_lines.size());
					break;
				}
				else
				{
					for(int j = 0 ; j < line.size() ; j++)
					{
						Cell& cell = m_cells[j][i];
						cell.x = j;
						cell.y = i;
						switch(line[j])
						{
						case ' ':
							cell.type = TOWER_CELL;
							break;
						case '-':
							cell.type = PATH_CELL;
							break;
						case '0':
							ASSERT(startPoint.first == -1 && startPoint.second == -1, "You can't have 2 start point on the map !!");
							startPoint.first = j;
							startPoint.second = i;
							cell.type = START_CELL;
							break;
						case 'X':
							cell.type = END_CELL;
							break;
						default:
							LOG("WARNING: Reach default case in Map::Map");
							cell.type = TOWER_CELL;
							break;
						}
					}
				}
			}
			// ========================================================================

		}
		else
		{
			LOG("Fail while parsing json:\n%s\n", reader.getFormatedErrorMessages().c_str());
		}

		// -----------------------------------------------------------------------------
		// Construct the border of the map
		std::vector<GameRenderer::MeshPoint> mapBorderPoints(4);
		mapBorderPoints[0].x = 0.0f;
		mapBorderPoints[0].y = 0.0f;
		mapBorderPoints[0].z = 0.0f;

		mapBorderPoints[1].x = MAP_SIZE;
		mapBorderPoints[1].y = 0.0f;
		mapBorderPoints[1].z = 0.0f;

		mapBorderPoints[2].x = MAP_SIZE;
		mapBorderPoints[2].y = MAP_SIZE;
		mapBorderPoints[2].z = 0.0f;
		
		mapBorderPoints[3].x = 0.0f;
		mapBorderPoints[3].y = MAP_SIZE;
		mapBorderPoints[3].z = 0.0f;
		
		GameRenderer& gr = GameRenderer::GetInstance();

		GameRenderer::GameMesh* borderMesh = gr.CreateMesh(mapBorderPoints, GameRenderer::SHADER_SIMPLE_TRANSFORM, true);

		GameRenderer::ShaderParams sp;
		sp.model = &m_modelMat;

		gr.AddMeshToRender(borderMesh, sp);

		// -----------------------------------------------------------------------------
		// Construct the path of the unit

		std::pair<int, int> currentCell = startPoint;
		std::pair<int, int> nextCell = std::make_pair(-1, -1);
		std::pair<int, int> previousCell = std::make_pair(-1, -1);
		std::vector<GameRenderer::MeshPoint> leftPathPoints;
		std::vector<GameRenderer::MeshPoint> rightPathPoints;


		bool finish = false;
		while(!finish)
		{
			ASSERT(currentCell.first >= 0 && currentCell.second >= 0, "Invalid currentCell(%d, %d)", currentCell.first, currentCell.second);
			m_path.push_back(&(m_cells[currentCell.first][currentCell.second]));

			switch(m_cells[currentCell.first][currentCell.second].type)
			{
			case PATH_CELL:
				{
					//finish = true;
					bool found = false;
					// Look for next cell of the path:
					if(!found && currentCell.first>0 && ((currentCell.first-1) != previousCell.first || currentCell.second != previousCell.second))
					{
						// Left neighbour
						if(m_cells[currentCell.first-1][currentCell.second].type == PATH_CELL || m_cells[currentCell.first-1][currentCell.second].type == END_CELL)
						{
							found = true;
							nextCell.first = currentCell.first-1;
							nextCell.second = currentCell.second;

							if(previousCell.first == currentCell.first && previousCell.second == currentCell.second-1)
							{
								// Previous cell was top, next is left
								
								leftPathPoints.push_back(GameRenderer::MeshPoint());
								leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].z = 0.0f;
								
								leftPathPoints.push_back(GameRenderer::MeshPoint());
								leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].z = 0.0f;
							}
							else if(previousCell.first == currentCell.first-1 && previousCell.second == currentCell.second)
							{
								ASSERT(false, "We can't have : Previous cell was left, next cell is left");
								/*
								// Previous cell was left, next cell is left
								leftPathPoints.push_back(GameRenderer::MeshPoint());
								leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].z = 0.0f;

								rightPathPoints.push_back(GameRenderer::MeshPoint());
								rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].z = 0.0f;*/
							}
							else if(previousCell.first == currentCell.first+1 && previousCell.second == currentCell.second)
							{
								// Previous cell was right, next cell is left
								leftPathPoints.push_back(GameRenderer::MeshPoint());
								leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].z = 0.0f;

								rightPathPoints.push_back(GameRenderer::MeshPoint());
								rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].z = 0.0f;
							}
							else if(previousCell.first == currentCell.first && previousCell.second == currentCell.second+1)
							{
								// Previous cell was bottom, next is left
								rightPathPoints.push_back(GameRenderer::MeshPoint());
								rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].z = 0.0f;

								rightPathPoints.push_back(GameRenderer::MeshPoint());
								rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].z = 0.0f;
							}
							else
							{
								finish = true;
							}

							// TODO
						}
					}

					if(!found && currentCell.second>0 && (currentCell.first != previousCell.first || (currentCell.second-1) != previousCell.second))
					{
						if(m_cells[currentCell.first][currentCell.second-1].type == PATH_CELL || m_cells[currentCell.first][currentCell.second-1].type == END_CELL)
						{
							found = true;
							// Top neighbour
							nextCell.first = currentCell.first;
							nextCell.second = currentCell.second-1;

							if(previousCell.first == currentCell.first && previousCell.second == currentCell.second-1)
							{
								// Previous cell was top, next is top
								ASSERT(false, "We can't have: Previous cell was top, next is top");
							}
							else if(previousCell.first == currentCell.first-1 && previousCell.second == currentCell.second)
							{
								// Previous cell was left, next is top
								rightPathPoints.push_back(GameRenderer::MeshPoint());
								rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].z = 0.0f;

								rightPathPoints.push_back(GameRenderer::MeshPoint());
								rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].z = 0.0f;
							}
							else if(previousCell.first == currentCell.first+1 && previousCell.second == currentCell.second)
							{
								// Previous cell was right, next is top
								leftPathPoints.push_back(GameRenderer::MeshPoint());
								leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].z = 0.0f;

								leftPathPoints.push_back(GameRenderer::MeshPoint());
								leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].z = 0.0f;
							}
							else
							{
								finish = true;
							}
						}
					}

					if(!found && currentCell.second<(m_cells.size()-1) && (currentCell.first != previousCell.first || (currentCell.second+1) != previousCell.second))
					{
						if(m_cells[currentCell.first][currentCell.second+1].type == PATH_CELL || m_cells[currentCell.first][currentCell.second+1].type == END_CELL)
						{
							found = true;
							// Bottom neighbour
							nextCell.first = currentCell.first;
							nextCell.second = currentCell.second+1;

							if(previousCell.first == currentCell.first && previousCell.second == currentCell.second-1)
							{
								// Previous was top, next is bottom

								leftPathPoints.push_back(GameRenderer::MeshPoint());
								leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].z = 0.0f;

								rightPathPoints.push_back(GameRenderer::MeshPoint());
								rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].z = 0.0f;
							}
							else if(previousCell.first == currentCell.first+1 && previousCell.second == currentCell.second)
							{
								// Previous was right, next is bottom

								rightPathPoints.push_back(GameRenderer::MeshPoint());
								rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].z = 0.0f;

								rightPathPoints.push_back(GameRenderer::MeshPoint());
								rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].z = 0.0f;
							}
							else if(previousCell.first == currentCell.first-1 && previousCell.second == currentCell.second)
							{
								// Previous was left, next is bottom
								leftPathPoints.push_back(GameRenderer::MeshPoint());
								leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].z = 0.0f;

								leftPathPoints.push_back(GameRenderer::MeshPoint());
								leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].z = 0.0f;
							}
							else
							{
								finish = true;
							}
						}
					}

					if(!found && currentCell.first<(m_cells.size()-1) && ((currentCell.first+1) != previousCell.first || currentCell.second != previousCell.second))
					{
						if(m_cells[currentCell.first+1][currentCell.second].type == PATH_CELL || m_cells[currentCell.first+1][currentCell.second].type == END_CELL)
						{
							found = true;
							// right neighbour
							nextCell.first = currentCell.first+1;
							nextCell.second = currentCell.second;

							if(previousCell.first == currentCell.first && previousCell.second == currentCell.second-1)
							{
								// Previous was top, next is right
								rightPathPoints.push_back(GameRenderer::MeshPoint());
								rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].z = 0.0f;

								rightPathPoints.push_back(GameRenderer::MeshPoint());
								rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].z = 0.0f;
							}
							else if(previousCell.first == currentCell.first && previousCell.second == currentCell.second+1)
							{
								// Previous was bottom, next is right
								leftPathPoints.push_back(GameRenderer::MeshPoint());
								leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].z = 0.0f;

								leftPathPoints.push_back(GameRenderer::MeshPoint());
								leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].z = 0.0f;
							}
							else if(previousCell.first == currentCell.first-1 && previousCell.second == currentCell.second)
							{
								// Previous was left, next is right
								leftPathPoints.push_back(GameRenderer::MeshPoint());
								leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
								leftPathPoints[leftPathPoints.size()-1].z = 0.0f;

								rightPathPoints.push_back(GameRenderer::MeshPoint());
								rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
								rightPathPoints[rightPathPoints.size()-1].z = 0.0f;
							}
							else
							{
								finish = true;
							}
						}
					}

					ASSERT(found, "No END_CELL nor PATH_CELL found after PATH_CELL");

					previousCell = currentCell;
					currentCell = nextCell;
					nextCell.first = -1;
					nextCell.second = -1;
					
					break;
				}
			case START_CELL:
				{
					bool found = false;
					// Look for next cell of the path:
					if(!found && currentCell.first>0)
					{
						// Left neighbour
						if(m_cells[currentCell.first-1][currentCell.second].type == PATH_CELL || m_cells[currentCell.first-1][currentCell.second].type == END_CELL)
						{
							found = true;
							nextCell.first = currentCell.first-1;
							nextCell.second = currentCell.second;

							// Update left path
							
							leftPathPoints.push_back(GameRenderer::MeshPoint());
							leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].z = 0.0f;

							leftPathPoints.push_back(GameRenderer::MeshPoint());
							leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].z = 0.0f;
							
							leftPathPoints.push_back(GameRenderer::MeshPoint());
							leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].z = 0.0f;
							
							// Update right path
							
							rightPathPoints.push_back(GameRenderer::MeshPoint());
							rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].z = 0.0f;

							rightPathPoints.push_back(GameRenderer::MeshPoint());
							rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].z = 0.0f;
						}
					}

					if(!found && currentCell.second>0)
					{
						if(m_cells[currentCell.first][currentCell.second-1].type == PATH_CELL || m_cells[currentCell.first][currentCell.second-1].type == END_CELL)
						{
							found = true;
							// Top neighbour
							nextCell.first = currentCell.first;
							nextCell.second = currentCell.second-1;

							// Update left path
							
							leftPathPoints.push_back(GameRenderer::MeshPoint());
							leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].z = 0.0f;

							leftPathPoints.push_back(GameRenderer::MeshPoint());
							leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].z = 0.0f;
							
							leftPathPoints.push_back(GameRenderer::MeshPoint());
							leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].z = 0.0f;
							
							// Update right path
							
							rightPathPoints.push_back(GameRenderer::MeshPoint());
							rightPathPoints[rightPathPoints.size()-1].x = (m_cells[currentCell.first][currentCell.second].x+1) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].y = (m_cells[currentCell.first][currentCell.second].y+1) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].z = 0.0f;

							rightPathPoints.push_back(GameRenderer::MeshPoint());
							rightPathPoints[rightPathPoints.size()-1].x = (m_cells[currentCell.first][currentCell.second].x+1) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].y = (m_cells[currentCell.first][currentCell.second].y) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].z = 0.0f;
						}
					}

					if(!found && currentCell.second<(m_cells.size()-1))
					{
						if(m_cells[currentCell.first][currentCell.second+1].type == PATH_CELL || m_cells[currentCell.first][currentCell.second+1].type == END_CELL)
						{
							found = true;
							// Bottom neighbour
							nextCell.first = currentCell.first;
							nextCell.second = currentCell.second+1;

							// Update left path
							
							leftPathPoints.push_back(GameRenderer::MeshPoint());
							leftPathPoints[leftPathPoints.size()-1].x = (m_cells[currentCell.first][currentCell.second].x) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].y = (m_cells[currentCell.first][currentCell.second].y) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].z = 0.0f;

							leftPathPoints.push_back(GameRenderer::MeshPoint());
							leftPathPoints[leftPathPoints.size()-1].x = (m_cells[currentCell.first][currentCell.second].x+1) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].y = (m_cells[currentCell.first][currentCell.second].y) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].z = 0.0f;
							
							leftPathPoints.push_back(GameRenderer::MeshPoint());
							leftPathPoints[leftPathPoints.size()-1].x = (m_cells[currentCell.first][currentCell.second].x+1) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].y = (m_cells[currentCell.first][currentCell.second].y+1) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].z = 0.0f;
							
							// Update right path
							
							rightPathPoints.push_back(GameRenderer::MeshPoint());
							rightPathPoints[rightPathPoints.size()-1].x = (m_cells[currentCell.first][currentCell.second].x) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].y = (m_cells[currentCell.first][currentCell.second].y) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].z = 0.0f;

							rightPathPoints.push_back(GameRenderer::MeshPoint());
							rightPathPoints[rightPathPoints.size()-1].x = (m_cells[currentCell.first][currentCell.second].x) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].y = (m_cells[currentCell.first][currentCell.second].y+1) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].z = 0.0f;
						}

					}

					if(!found && currentCell.first<(m_cells.size()-1))
					{
						if(m_cells[currentCell.first+1][currentCell.second].type == PATH_CELL || m_cells[currentCell.first+1][currentCell.second].type == END_CELL)
						{
							found = true;
							// right neighbour
							nextCell.first = currentCell.first+1;
							nextCell.second = currentCell.second;

							// Update left path

							leftPathPoints.push_back(GameRenderer::MeshPoint());
							leftPathPoints[leftPathPoints.size()-1].x = (m_cells[currentCell.first][currentCell.second].x) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].y = (m_cells[currentCell.first][currentCell.second].y+1) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].z = 0.0f;

							leftPathPoints.push_back(GameRenderer::MeshPoint());
							leftPathPoints[leftPathPoints.size()-1].x = (m_cells[currentCell.first][currentCell.second].x) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].y = (m_cells[currentCell.first][currentCell.second].y) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].z = 0.0f;
							
							leftPathPoints.push_back(GameRenderer::MeshPoint());
							leftPathPoints[leftPathPoints.size()-1].x = (m_cells[currentCell.first][currentCell.second].x) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].y = (m_cells[currentCell.first][currentCell.second].y+1) * MAP_SIZE/m_cells.size();
							leftPathPoints[leftPathPoints.size()-1].z = 0.0f;
							
							// Update right path
							
							rightPathPoints.push_back(GameRenderer::MeshPoint());
							rightPathPoints[rightPathPoints.size()-1].x = (m_cells[currentCell.first][currentCell.second].x) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].y = (m_cells[currentCell.first][currentCell.second].y+1) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].z = 0.0f;

							rightPathPoints.push_back(GameRenderer::MeshPoint());
							rightPathPoints[rightPathPoints.size()-1].x = (m_cells[currentCell.first][currentCell.second].x+1) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].y = (m_cells[currentCell.first][currentCell.second].y+1) * MAP_SIZE/m_cells.size();
							rightPathPoints[rightPathPoints.size()-1].z = 0.0f;

						}
					}

					ASSERT(found, "No END_CELL nor PATH_CELL found after START_CELL");

					previousCell = currentCell;
					currentCell = nextCell;
					nextCell.first = -1;
					nextCell.second = -1;
					break;
				}
			case END_CELL:
				finish = true;
				if(previousCell.first == currentCell.first-1 && previousCell.second == currentCell.second)
				{
					// Previous cell was left
					leftPathPoints.push_back(GameRenderer::MeshPoint());
					leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
					leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second) * MAP_SIZE/m_cells.size();
					leftPathPoints[leftPathPoints.size()-1].z = 0.0f;

					leftPathPoints.push_back(GameRenderer::MeshPoint());
					leftPathPoints[leftPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
					leftPathPoints[leftPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
					leftPathPoints[leftPathPoints.size()-1].z = 0.0f;

					rightPathPoints.push_back(GameRenderer::MeshPoint());
					rightPathPoints[rightPathPoints.size()-1].x = (currentCell.first+1) * MAP_SIZE/m_cells.size();
					rightPathPoints[rightPathPoints.size()-1].y = (currentCell.second+1) * MAP_SIZE/m_cells.size();
					rightPathPoints[rightPathPoints.size()-1].z = 0.0f;

					

				}
				break;
			case TOWER_CELL:
				ASSERT(false, "We should not reach the TOWER_CELL case");
				break;
			default:
				ASSERT(false, "We should not reach the default case");
				break;
			}

			
			
		}

		GameRenderer::GameMesh* pathLeftMesh = gr.CreateMesh(leftPathPoints, GameRenderer::SHADER_SIMPLE_TRANSFORM, false);
		gr.AddMeshToRender(pathLeftMesh, sp);
			
		GameRenderer::GameMesh* pathRightMesh = gr.CreateMesh(rightPathPoints, GameRenderer::SHADER_SIMPLE_TRANSFORM, false);
		gr.AddMeshToRender(pathRightMesh, sp);

		// -----------------------------------------------------------------------------

		

		LOG("<-MAP::MAP\n");
	}

	Map::~Map()
	{
	}

	double Map::GetSizeCell()
	{
		return MAP_SIZE/m_cells.size();
	}
}